package com.tanhua.admin.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanhua.admin.mapper.AnalysisMapper;
import com.tanhua.admin.mapper.LogMapper;
import com.tanhua.model.admin.Analysis;
import com.tanhua.model.dto.LastYearDto;
import com.tanhua.model.dto.ThisYearDto;
import com.tanhua.model.enums.UserInfoType;
import com.tanhua.model.vo.AnalysisGetUserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Service
public class AnalysisService extends ServiceImpl<AnalysisMapper, Analysis> {

    @Autowired
    private AnalysisMapper analysisMapper;

    @Autowired
    private LogMapper logMapper;

       /**
     * 定时统计日志数据到统计表中
     * 1、查询tb_log表中的数 （每日注册用户数，每日登陆用户，活跃的用户数据，次日留存的用户）
     * 2、构造AnalysisByDay对象
     * 3、完成统计数据的更新或者保存
     */
      public Analysis analysis() throws ParseException {
        //1、定义查询的日期
        String todayStr = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String yesdayStr = DateUtil.yesterday().toString("yyyy-MM-dd");
        //2、统计数据-注册数量
        Integer regCount = logMapper.queryByTypeAndLogTime("0102", todayStr);
        //3、统计数据-登录数量
        Integer loginCount = logMapper.queryByTypeAndLogTime("0101", todayStr);
        //4、统计数据-活跃数量
        Integer activeCount = logMapper.queryByLogTime(todayStr);
        //5、统计数据-次日留存
        Integer numRetention1d = logMapper.queryNumRetention1d(todayStr, yesdayStr);
        //6、根据日期查询数据
        QueryWrapper<Analysis> qw = new QueryWrapper<Analysis>();
        qw.eq("record_date",new SimpleDateFormat("yyyy-MM-dd").parse(todayStr));
        //7、构造Analysis对象
        Analysis analysis = analysisMapper.selectOne(qw);
        //8、如果存在，更新，如果不存在保存
        if(analysis != null) {
            analysis.setNumRegistered(regCount);
            analysis.setNumLogin(loginCount);
            analysis.setNumActive(activeCount);
            analysis.setNumRetention1d(numRetention1d);
            analysis.setUpdated(new Date());
            analysisMapper.updateById(analysis);
        }else {
            analysis = new Analysis();
            analysis.setNumRegistered(regCount);
            analysis.setNumLogin(loginCount);
            analysis.setNumActive(activeCount);
            analysis.setNumRetention1d(numRetention1d);
            analysis.setRecordDate(new SimpleDateFormat("yyyy-MM-dd").parse(todayStr));
            analysis.setCreated(new Date());
            analysis.setUpdated(new Date());
            analysisMapper.insert(analysis);
        }
        return analysis;
    }
    public Integer queryCumulativeUsers() {
        return analysisMapper.queryCumulativeUsers();
    }

    public Analysis querySummary(Date now) {
        //5、根据当前时间查询AnalysisByDay数据
        LambdaQueryWrapper<Analysis> qw = Wrappers.<Analysis>lambdaQuery();
        qw.eq(Analysis::getRecordDate, DateUtil.format(now, "yyyy-MM-dd"));
        return analysisMapper.selectOne(qw);
    }

    //过去三十天活跃数
    public Integer getNumActive30() {
        return analysisMapper.queryThiryDaysUser();
    }

    //过去七天活跃用户
    public Integer getNumActive7() {
        return analysisMapper.querySevenDaysUser();
    }

    //今日活跃用户
    public Integer getNumTodayActive() {
        return analysisMapper.queryTodayActive();
    }

    //今日登录用户
    public Integer getNumLogin() {
        return analysisMapper.queryTodayLogin();
    }
    //今日增长
    public Integer getNumRegistered() {
        Integer all = analysisMapper.queryRegistered();
        Integer beforToday = analysisMapper.queryTodayRegistered();
        int i = all - beforToday == 0 ? 0 : all - beforToday;
        return i ;
    }

    /**
     * 新增、活跃用户、次日留存率
     *
     * @param sd
     * @param ed
     * @param type
     * @return
     */
    public AnalysisGetUserVo getUsers(Long sd, Long ed, Integer type) {

        //创建返回值的实体类用来封装数据
        AnalysisGetUserVo vo = new AnalysisGetUserVo();

        //今年的数据
        //准备查询日期的范围
        String startDateThisYear = DateUtil.date(sd).toString("yyyy-MM-dd");//将客户端传进来的日期毫秒值转换为数据库相同格式的字符串类型
        String endDateThisYear = DateUtil.date(ed).toString("yyyy-MM-dd");//将客户端传进来的日期毫秒值转换为数据库相同格式的字符串类型
        //从数据库查询日期范围内的数据
        List<Analysis> analysisListThisYear = query().between("record_date", startDateThisYear, endDateThisYear).list();
        //把每天的数据转换成AnalysisChartDataItem对象
        List<ThisYearDto> thisYearList = new ArrayList<>();
        for (Analysis analysis : analysisListThisYear) {
            //把去年每天的数据，转换成AnalysisChartDataItem对象
            ThisYearDto item = new ThisYearDto();
            //设置日期
            item.setTitle(DateUtil.format(analysis.getRecordDate(), "yyyy-MM-dd"));
            //通过UserInfoType枚举类101新增用户数 102活跃用户数 103次日留存率
            //根据客户端传进来的类型查询对应的数据
            if (type.equals(UserInfoType.NEWUSER.getType())) {  //101新增用户数
                item.setAmount(analysis.getNumRegistered());
            } else if (type.equals(UserInfoType.ACTIVEUSER.getType())) {  //102活跃用户数
                item.setAmount(analysis.getNumActive());
            } else if (type.equals(UserInfoType.NEXTDAYLEFT.getType())) {  //103次日留存率
                item.setAmount(analysis.getNumRetention1d());
            }
            //遍历好的数据放到封装日期范围的list里面
            thisYearList.add(item);
        }
        //把今年的AnalysisChartDataItem集合，放到vo的thisYear里
        vo.setThisYear(thisYearList);


        //去年的数据
        //准备去年的日期范围
        String startDateLastYear = DateUtil.date(sd).offset(DateField.YEAR, -1).toString("yyyy-MM-dd");//将客户端传进来的日期毫秒值转换为数据库相同格式的字符串类型
        String endDateLastYear = DateUtil.date(ed).offset(DateField.YEAR, -1).toString("yyyy-MM-dd");//将客户端传进来的日期毫秒值转换为数据库相同格式的字符串类型
        //根据日期范围查询数据库
        List<Analysis> analysisListLastYear = query().between("record_date", startDateLastYear, endDateLastYear).list();
        //把去年每天的数据，转换成AnalysisChartDataItem对象
        ArrayList<LastYearDto> lastYearList = new ArrayList<>();
        for (Analysis analysis : analysisListLastYear) {
            //创建一个封装数据的item类
            LastYearDto item = new LastYearDto();
            item.setTitle(DateUtil.format(analysis.getRecordDate(), "yyyy-MM-dd"));
            if (type.equals(UserInfoType.NEWUSER.getType())) {     //101新增用户数
                item.setAmount(analysis.getNumRegistered());
            } else if (type.equals(UserInfoType.ACTIVEUSER.getType())) {     //102活跃用户数
                item.setAmount(analysis.getNumActive());
            } else if (type.equals(UserInfoType.NEXTDAYLEFT.getType())) {   //103次日留存率
                item.setAmount(analysis.getNumRetention1d());
            }
            //把数据封装到集合里
            lastYearList.add(item);
        }
        //把去年的AnalysisChartDataItem集合，放到vo的thisYear里
        vo.setLastYear(lastYearList);
        //返回Vo对象
        return vo;
    }

/**
     * 新增、活跃用户、次日留存率
     *
     * @param sd
     * @param ed
     * @param type
     * @return
     */
/*
    public AnalysisGetUserVo getUsers(Long sd, Long ed, Integer type) {
        //开始时间
        DateTime startTime = DateUtil.date(sd);
        String sdTime = startTime.toDateStr();

        //结束时间
        DateTime endTime = DateUtil.date(ed);
        String edTime =endTime.toDateStr();
        //创建VO对象，封装数据，返给前端
        AnalysisGetUserVo analysisGetUserVo = new AnalysisGetUserVo();
        //创建集合封装数据
        List<Object> thisYear = new ArrayList<>();
        List<Object> lastYear = new ArrayList<>();
        //判断新增
        if (type.equals(UserInfoType.NEWUSER.getType())) {
            thisYear = analysisMapper.queryThisYear(sdTime, edTime, type);
            lastYear = analysisMapper.queryLastYear(sdTime, edTime, type);
        //判断活跃用户
        } else if (type.equals(UserInfoType.ACTIVEUSER.getType())) {
            thisYear = analysisMapper.queryThisYear(sdTime, edTime, type);
           lastYear = analysisMapper.queryLastYear(sdTime, edTime, type);
        //判断次日留存率
        } else if (type.equals(UserInfoType.NEXTDAYLEFT.getType())) {
            thisYear = analysisMapper.queryThisYear(sdTime, edTime, type);
            lastYear = analysisMapper.queryLastYear(sdTime, edTime, type);
        }
        //将数据封装给Vo对象
        analysisGetUserVo.setThisyear(thisYear);
        analysisGetUserVo.setLastyear(lastYear);

        //返回Vo对象
        return analysisGetUserVo;
    }*/
}